package org.starsource.forum.client.widget;

import com.google.gwt.i18n.client.LocaleInfo;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.SimplePanel;

public class DecoratorPanel extends SimplePanel {

	private String styleName = "gwter-DecoratorPanel";
	
	private String[] outerRowStyleNames = {
		"OuterTopTr", 
		"OuterMiddleTr", 
		"OuterBottomTr"
	};
	
	private String[] outerColStyleNames = {
		"OuterTopTd",
		"OuterMiddleTd",
		"OuterBottomTd"
	};
	
	private String[] innerTableStyleNames = {
		"InnerTopTable",
		"InnerMiddleTable", 
		"InnerBottomTable"
	};
	
	private String[] innerRowStyleNames = {
		"InnerTopTr", 
		"InnerMiddleTr", 
		"InnerBottomTr"
	};
	
	private String[][] innerColStyleNames = {
		{"InnerTopLeftTd", "InnerTopCenterTd", "InnerTopRightTd"},
		{"InnerMiddleLeftTd", "InnerMiddleCenterTd", "InnerMiddleRightTd"},
		{"InnerBottomLeftTd", "InnerBottomCenterTd", "InnerBottomRightTd"}
	};
	
	private int headRow = 0;
	private int headCol = 1;
	
	private int containerRow = 1;
	private int containerCol = 1;
	
	private int footRow = 2;
	private int footCol = 1;
	
	private Element[][] innerElems = new Element[3][3];
	
	private Element createOuterTr(int row) {
		Element trElem = DOM.createTR();
		setStyleName(trElem, outerRowStyleNames[row]);
		
		DOM.appendChild(trElem, createOuterTd(row));
		return trElem;
	}

	private Element createOuterTd(int row) {
		Element outerTd = DOM.createTD();
		setStyleName(outerTd, outerColStyleNames[row]);
		DOM.appendChild(outerTd, createInnerTable(row));
		return outerTd;
	}

	
	private Element createInnerTable(int row) {
		Element innerTable = DOM.createTable();
		Element innerTbody = DOM.createTBody();
		DOM.appendChild(innerTable, innerTbody);
		DOM.setElementPropertyInt(innerTable, "cellSpacing", 0);
		DOM.setElementPropertyInt(innerTable, "cellPadding", 0);
		
		setStyleName(innerTable, innerTableStyleNames[row]);
		
		DOM.appendChild(innerTbody, createInnerTR(row));
		
		return innerTable;
	}
	
	private Element createInnerTR(int row) {
		Element innerTr = DOM.createTR();
		setStyleName(innerTr, innerRowStyleNames[row]);

		if (LocaleInfo.getCurrentLocale().isRTL()) {
			for(int i = innerColStyleNames.length - 1; i >= 0; i --) {
				DOM.appendChild(innerTr, createInnerTd(row, i));
			}
		} else {
			for(int i = 0; i < innerColStyleNames.length ; i ++) {
				DOM.appendChild(innerTr, createInnerTd(row, i));
			}
		}
		return innerTr;
	}
	
	private Element createInnerTd(int row, int col) {
		Element innerTd = DOM.createTD();
		Element innerDiv = DOM.createDiv();
		DOM.appendChild(innerTd, innerDiv);
		
		setStyleName(innerTd, innerColStyleNames[row][col]);
		setStyleName(innerDiv, innerColStyleNames[row][col] + "Div");
		if (row == headRow && col == headCol) {
			headElem = innerDiv;
		}
		if (row == containerRow && col == containerCol) {
			containerElem = innerDiv;
		}
		if (row == footRow && col == footCol) {
			footElem = innerDiv;
		}
		
		innerElems[row][col] = innerDiv;
		return innerTd;
	}
	
	/**
	 * The container element at the center of the panel.
	 */
	private Element headElem;
	
	private Element containerElem;
	
	private Element footElem;

	/**
	 * The table body element.
	 */
	private Element outerTbody;

	/**
	 * Create a new {@link DecoratorPanel}.
	 */
	public DecoratorPanel() {
		super(DOM.createTable());

		// Add a tbody
		Element outerTable = getElement();
		outerTbody = DOM.createTBody();
		DOM.appendChild(outerTable, outerTbody);
		DOM.setElementPropertyInt(outerTable, "cellSpacing", 0);
		DOM.setElementPropertyInt(outerTable, "cellPadding", 0);
		
		// Add each row
		for (int i = 0; i < outerRowStyleNames.length; i++) {
			Element row = createOuterTr(i);
			DOM.appendChild(outerTbody, row);
		}

		// Set the overall style name
		setStyleName(styleName);
	}

	/**
	 * Get a specific Element from the panel.
	 * 
	 * @param row the row index
	 * @param cell the cell index
	 * @return the Element at the given row and cell
	 */
	protected Element getCellElement(int row, int cell) {
		return innerElems[row][cell];
	}

	@Override
	protected Element getContainerElement() {
		return containerElem;
	}
	
	protected Element getHeadElement() {
		return headElem;
	}
	
	protected Element getFootElement() {
		return footElem;
	}
	
}